package com.jiajie.gsaccessingdatajpa.concurrent.monitor;

/**
 * Java monitor实现生产者/消费者
 * 简化版本，只允许一个生产者和一个消费者
 *
 * @author jie
 * @date 2021/8/21 8:47 PM
 */
public class BoundedBuffer {
    private int numSlots = 0;
    private double[] buffer = null;
    private int putIn = 0, takeOut = 0;
    private int count = 0;

    public BoundedBuffer(int numSlots){
        if (numSlots <= 0) {
            throw new IllegalArgumentException("numberSlots<=0");
        }
        this.numSlots = numSlots;
        buffer = new double[numSlots];
        System.out.println("BoundedBuffer alive, numSlots=" + numSlots);
    }

    public synchronized void deposit(double value){
        while (count == numSlots){
            try {
                wait();
            } catch (InterruptedException e) {
                System.out.println("interrupted out of wait");
            }
        }
        buffer[putIn] = value;
        putIn = (putIn + 1) % numSlots;
        count++;
        if (count == 1) {
            //  唤醒等待的consumer
            notify();
        }
    }

    public synchronized double fetch(){
        double value;
        while (count == 0) {
            try {
                wait();
            } catch (InterruptedException e) {
                System.out.println("interrupted out of wait");
            }
        }
        value = buffer[takeOut];
        takeOut = (takeOut + 1) % numSlots;
        // wake up the producer
        count--;
        if (count == numSlots -1 ){
            // 唤醒等待的producer
            notify();
        }
        return value;
    }
}
